package UI;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.tree.*;
import javax.swing.plaf.basic.*;
import Utils.LocationFinder.*;
import java.util.*;
import Core.*;

class Test
{
    private AutoCompleteBox acBox = null;

    public Test() {
        JFrame fr=new JFrame("TEST ComboBox");
	JPanel p = new JPanel();
        p.setLayout( new BorderLayout() );

        TestProvider t = new TestProvider();
	fr.getContentPane().add(p);
        acBox = new AutoCompleteBox();
        acBox.SetFinder(new AddressFinder(t));

        p.add("South",acBox);
        fr.pack();
        fr.show();
    }
    public static void main( String[] args ) {
      Test test=new Test();
    }
}

class TestProvider implements IMapProvider {
    public      ArrayList<Node> nodes;
    public    ArrayList<Street> streets;
    public ArrayList<Link> links;

        void AddLink(Node a, Node b, Street street, double dist, int s, int e) {
            Link l = new Link(ObjectId.NewId(), b.Id(), street.Id());
            l.SetDistance(dist);
            l.SetStartPoint(s);
            l.SetEndPoint(e);
            a.AddLink(l);
            links.add(l);
        }

        public TestProvider() {
            nodes = new ArrayList<Node>();
            streets = new ArrayList<Street>();
            links = new ArrayList<Link>();


            /*for(int i = 0; i < 10; i++) {
                nodes.add(new Node(ObjectId.NewId(), new Coordinates(0, 0)));
            }*/
// creare noduri:
            nodes.add(new Node(ObjectId.NewId(), new Coordinates(0, 0)));
            nodes.add(new Node(ObjectId.NewId(), new Coordinates(0, 1)));
            nodes.add(new Node(ObjectId.NewId(), new Coordinates(0, 2)));
            nodes.add(new Node(ObjectId.NewId(), new Coordinates(0, 3)));
            nodes.add(new Node(ObjectId.NewId(), new Coordinates(1, 0)));
            nodes.add(new Node(ObjectId.NewId(), new Coordinates(1, 1)));
            nodes.add(new Node(ObjectId.NewId(), new Coordinates(1, 2)));
            nodes.add(new Node(ObjectId.NewId(), new Coordinates(1, 3)));
            nodes.add(new Node(ObjectId.NewId(), new Coordinates(2, 0)));
            nodes.add(new Node(ObjectId.NewId(), new Coordinates(2, 1)));


            //Adauga strazi (orizontal)
              Street s0 = new Street(ObjectId.NewId(), StreetType.Street,
                            "str0", nodes.get(0),nodes.get(3));
                for(int j = 0; j < 5; j++)
                    s0.AddCoordinate(new Coordinates(0, j));
               streets.add(s0);

               Street s1 = new Street(ObjectId.NewId(), StreetType.Street
                         ,"str1", nodes.get(4),nodes.get(7));
                for(int j = 0; j < 5; j++)
                    s1.AddCoordinate(new Coordinates(1, j));
                streets.add(s1);

                Street s2 = new Street(ObjectId.NewId(), StreetType.Street,
                                "strada2", nodes.get(8),nodes.get(9));
                for(int j = 0; j < 5; j++)
                    s2.AddCoordinate(new Coordinates(2, j));

                streets.add(s2);

                //Adauga strazi verticale;

                Street s3 = new Street(ObjectId.NewId(), StreetType.Street,
                                "str3", nodes.get(0),nodes.get(8));
                for(int j = 0; j < 5; j++)
                    s3.AddCoordinate(new Coordinates(j, 0));

                streets.add(s3);

                 for(int i = 0; i < 3; i++) {
                Street s = new Street(ObjectId.NewId(), StreetType.Street);
                //,"str", nodes.get(0),nodes.get(3));
                for(int j = 0; j < 6; j++) {
                    s.AddCoordinate(new Coordinates(i, i));
                }

                streets.add(s);
            }


            // Adauga link-uri (orizontal).
            AddLink(nodes.get(0), nodes.get(1), streets.get(0), 10, 0, 1);
            AddLink(nodes.get(1), nodes.get(2), streets.get(0), 20, 1, 2);
            AddLink(nodes.get(2), nodes.get(3), streets.get(0), 10, 2, 3);

            //Linkuri bidirectionale
            AddLink(nodes.get(1), nodes.get(0), streets.get(0), 10, 1, 0);
            AddLink(nodes.get(2), nodes.get(1), streets.get(0), 20, 2, 1);
            AddLink(nodes.get(3), nodes.get(2), streets.get(0), 10, 3, 2);


            AddLink(nodes.get(4), nodes.get(5), streets.get(1), 3, 0, 1);
            AddLink(nodes.get(5), nodes.get(6), streets.get(1), 2, 1, 2);
            AddLink(nodes.get(6), nodes.get(7), streets.get(1), 1, 2, 3);

            AddLink(nodes.get(8), nodes.get(9), streets.get(2), 2, 0, 1);

            // Vertical.
            AddLink(nodes.get(0), nodes.get(4), streets.get(3), 2, 0, 1);
            AddLink(nodes.get(4), nodes.get(8), streets.get(3), 5, 1, 2);

            AddLink(nodes.get(1), nodes.get(5), streets.get(4), 30, 0, 1);

            AddLink(nodes.get(2), nodes.get(6), streets.get(5), 4, 0, 1);
        }



        public String Name() {
            throw new UnsupportedOperationException("Not supported yet.");
        }

        public int ZoomLevels() {
            throw new UnsupportedOperationException("Not supported yet.");
        }

        public Region MapBounds() {
            throw new UnsupportedOperationException("Not supported yet.");
        }

        public Region2D MapBounds(int zoomLevel) {
            throw new UnsupportedOperationException("Not supported yet.");
        }

        public IProjection Projection() {
            throw new UnsupportedOperationException("Not supported yet.");
        }

        public int LayerCount() {
            throw new UnsupportedOperationException("Not supported yet.");
        }

        public boolean HasLayer(LayerType layerType) {
            throw new UnsupportedOperationException("Not supported yet.");
        }

        public ILayer GetLayer(ObjectId layerId) {
            throw new UnsupportedOperationException("Not supported yet.");
        }

        public Iterator<ILayer> GetLayerIterator() {
            throw new UnsupportedOperationException("Not supported yet.");
        }

        public double TileSize() {
            throw new UnsupportedOperationException("Not supported yet.");
        }

        public int TileCount(int zoomLevel) {
            throw new UnsupportedOperationException("Not supported yet.");
        }

        public TileInfo GetTile(Core.Point point, int zoomLevel) {
            throw new UnsupportedOperationException("Not supported yet.");
        }

        public void GetTiles(Region2D region, int zoomLevel, java.util.List<TileInfo> list) {
            throw new UnsupportedOperationException("Not supported yet.");
        }

        public Image LoadTile(ObjectId tileId) {
            throw new UnsupportedOperationException("Not supported yet.");
        }

        public int NodeNumber() {
            return nodes.size();
        }

        public Iterator<Node> GetNodeIterator() {
            return nodes.iterator();
        }

        public Node GetNode(ObjectId nodeID) {
            for(int i = 0; i < nodes.size(); i++) {
                Node n = nodes.get(i);
                if(n.Id().equals(nodeID)) {
                    return n;
                }
            }

            throw new RuntimeException("Nu trebuie sa se ajunga aici!!!");
        }

        public Core.Color StreetColor(StreetType streetType) {
            throw new UnsupportedOperationException("Not supported yet.");
        }

        public int MarkerCount(ObjectId layerID) {
            throw new UnsupportedOperationException("Not supported yet.");
        }

        public Iterator<Marker> GetMarkerIterator(ObjectId layerID) {
            throw new UnsupportedOperationException("Not supported yet.");
        }

        public Marker GetMarker(ObjectId markerID, ObjectId layerID) {
            throw new UnsupportedOperationException("Not supported yet.");
        }

        public Image LoadMarkerIcon(ObjectId layerID) {
            throw new UnsupportedOperationException("Not supported yet.");
        }

        public void Load(String location) {
            throw new UnsupportedOperationException("Not supported yet.");
        }

        public void Save(String location) {
            throw new UnsupportedOperationException("Not supported yet.");
        }



        public int StreetCount() {
            return streets.size();
        }

 //    public Iterator<Street> IteratorStreet(){
 //       Collection collection = streets_.values();
 //       Iterator i = collection.iterator();
 //       return i;
 //   }

        public Iterator<Street> GetStreetIterator() {
             Collection coll=streets;//.contains(streets);
             if(coll!=null){
             Iterator ii=coll.iterator();
           // return streets.iterator();
             Iterator<Street> i = ii;
             return i;
             }
            throw new UnsupportedOperationException("Not supported yet.");
        }

        public Street GetStreet(ObjectId streetID) {
            for(int i = 0; i < streets.size(); i++) {
                Street s = streets.get(i);
                if(s.Id().equals(streetID)) {
                    return s;
                }
            }

            throw new RuntimeException("Nu trebuie sa se ajunga aici!!!");
        }
    }

class AutoCompleteBox extends JComboBox {
    private JTextField tf;
    private AddressFinder finder_;
    
    public AutoCompleteBox() {
        super();
        SetEditor(new BasicComboBoxEditor());
        this.setEditable(true);
    }

    public void SetFinder(AddressFinder value) {
        finder_ = value;
    }

    private void showList(String text) {
        this.removeAllItems();
        if(text.length() == 0) {
            this.hidePopup();
            return;
        }

        java.util.List<String> list = finder_.GetSuggestions(text);
        for(String s : list) {
            this.addItem(s);
        }

        if(list.size() > 1) {
            this.showPopup();
        }
        else this.hidePopup();
    }
    
    public void SetEditor(ComboBoxEditor anEditor) {
        super.setEditor(anEditor);
        if (anEditor.getEditorComponent() instanceof JTextField) {
            tf=(JTextField)anEditor.getEditorComponent();
            tf.addKeyListener(new KeyAdapter()
                  {
                    public void keyReleased(KeyEvent ev) {
                        if(finder_ == null) return;
                      char key=ev.getKeyChar();
                      
                      if(ev.getKeyCode() != KeyEvent.VK_BACK_SPACE) {
                        if (! (Character.isLetterOrDigit(key)||Character.isSpaceChar(key) )) return;
                      }
                      String text = tf.getText();
                      showList(text);
                      tf.setText(text);
                    }
              } );
        }
    }
}